home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 25 / Cream of the Crop 25.iso / program / tcpdumpb.zip / print-ether.c < prev    next >
C/C++ Source or Header  |  1997-02-14  |  7KB  |  201 lines

  1. /*
  2.  * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996
  3.  *      The Regents of the University of California.  All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that: (1) source code distributions
  7.  * retain the above copyright notice and this paragraph in its entirety, (2)
  8.  * distributions including binary code include the above copyright notice and
  9.  * this paragraph in its entirety in the documentation or other materials
  10.  * provided with the distribution, and (3) all advertising materials mentioning
  11.  * features or use of this software display the following acknowledgement:
  12.  * ``This product includes software developed by the University of California,
  13.  * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
  14.  * the University nor the names of its contributors may be used to endorse
  15.  * or promote products derived from this software without specific prior
  16.  * written permission.
  17.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
  18.  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
  19.  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  20.  */
  21. #ifndef lint
  22. static char rcsid[] =
  23.     "@(#) $Header: print-ether.c,v 1.42 96/07/23 14:17:23 leres Exp $ (LBL)";
  24. #endif
  25.  
  26. #include <sys/param.h>
  27. #include <sys/time.h>
  28. #include <sys/socket.h>
  29.  
  30. #if __STDC__
  31. struct mbuf;
  32. struct rtentry;
  33. #endif
  34. #include <net/if.h>
  35.  
  36. #include <netinet/in.h>
  37. #include <netinet/if_ether.h>
  38. #include <netinet/in_systm.h>
  39. #include <netinet/ip.h>
  40. #ifndef __EMX__
  41. #include <netinet/ip_var.h>
  42. #endif
  43. #include <netinet/udp.h>
  44. #include <netinet/udp_var.h>
  45. #include <netinet/tcp.h>
  46. #ifndef __EMX__
  47. #include <netinet/tcpip.h>
  48. #endif
  49.  
  50. #include <stdio.h>
  51. #include <pcap.h>
  52.  
  53. #include "interface.h"
  54. #include "addrtoname.h"
  55. #include "ethertype.h"
  56.  
  57. const u_char *packetp;
  58. const u_char *snapend;
  59.  
  60. static inline void
  61. ether_print(register const u_char *bp, u_int length)
  62. {
  63.         register const struct ether_header *ep;
  64.  
  65.         ep = (const struct ether_header *)bp;
  66.         if (qflag)
  67.                 (void)printf("%s %s %d: ",
  68.                              etheraddr_string(ESRC(ep)),
  69.                              etheraddr_string(EDST(ep)),
  70.                              length);
  71.         else
  72.                 (void)printf("%s %s %s %d: ",
  73.                              etheraddr_string(ESRC(ep)),
  74.                              etheraddr_string(EDST(ep)),
  75.                              etherproto_string(ep->ether_type),
  76.                              length);
  77. }
  78.  
  79. /*
  80.  * This is the top level routine of the printer.  'p' is the points
  81.  * to the ether header of the packet, 'tvp' is the timestamp,
  82.  * 'length' is the length of the packet off the wire, and 'caplen'
  83.  * is the number of bytes actually captured.
  84.  */
  85. void
  86. ether_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p)
  87. {
  88.         u_int caplen = h->caplen;
  89.         u_int length = h->len;
  90.         struct ether_header *ep;
  91.         u_short ether_type;
  92.         extern u_short extracted_ethertype;
  93.  
  94.         ts_print(&h->ts);
  95.  
  96.         if (caplen < sizeof(struct ether_header)) {
  97.                 printf("[|ether]");
  98.                 goto out;
  99.         }
  100.  
  101.         if (eflag)
  102.                 ether_print(p, length);
  103.  
  104.         /*
  105.          * Some printers want to get back at the ethernet addresses,
  106.          * and/or check that they're not walking off the end of the packet.
  107.          * Rather than pass them all the way down, we set these globals.
  108.          */
  109.         packetp = p;
  110.         snapend = p + caplen;
  111.  
  112.         length -= sizeof(struct ether_header);
  113.         caplen -= sizeof(struct ether_header);
  114.         ep = (struct ether_header *)p;
  115.         p += sizeof(struct ether_header);
  116.  
  117.         ether_type = ntohs(ep->ether_type);
  118.  
  119.         /*
  120.          * Is it (gag) an 802.3 encapsulation?
  121.          */
  122.         extracted_ethertype = 0;
  123.         if (ether_type < ETHERMTU) {
  124.                 /* Try to print the LLC-layer header & higher layers */
  125.                 if (llc_print(p, length, caplen, ESRC(ep), EDST(ep)) == 0) {
  126.                         /* ether_type not known, print raw packet */
  127.                         if (!eflag)
  128.                                 ether_print((u_char *)ep, length);
  129.                         if (extracted_ethertype) {
  130.                                 printf("(LLC %s) ",
  131.                                etherproto_string(htons(extracted_ethertype)));
  132.                         }
  133.                         if (!xflag && !qflag)
  134.                                 default_print(p, caplen);
  135.                 }
  136.         } else if (ether_encap_print(ether_type, p, length, caplen) == 0) {
  137.                 /* ether_type not known, print raw packet */
  138.                 if (!eflag)
  139.                         ether_print((u_char *)ep, length + sizeof(*ep));
  140.                 if (!xflag && !qflag)
  141.                         default_print(p, caplen);
  142.         }
  143.         if (xflag)
  144.                 default_print(p, caplen);
  145.  out:
  146.         putchar('\n');
  147. }
  148.  
  149. /*
  150.  * Prints the packet encapsulated in an Ethernet data segment
  151.  * (or an equivalent encapsulation), given the Ethernet type code.
  152.  *
  153.  * Returns non-zero if it can do so, zero if the ethertype is unknown.
  154.  *
  155.  * Stuffs the ether type into a global for the benefit of lower layers
  156.  * that might want to know what it is.
  157.  */
  158.  
  159. u_short extracted_ethertype;
  160.  
  161. int
  162. ether_encap_print(u_short ethertype, const u_char *p,
  163.     u_int length, u_int caplen)
  164. {
  165.         extracted_ethertype = ethertype;
  166.  
  167.         switch (ethertype) {
  168.  
  169.         case ETHERTYPE_IP:
  170.                 ip_print(p, length);
  171.                 return (1);
  172.  
  173.         case ETHERTYPE_ARP:
  174.         case ETHERTYPE_REVARP:
  175.                 arp_print(p, length, caplen);
  176.                 return (1);
  177.  
  178.         case ETHERTYPE_DN:
  179.                 decnet_print(p, length, caplen);
  180.                 return (1);
  181.  
  182.         case ETHERTYPE_ATALK:
  183.                 if (vflag)
  184.                         fputs("et1 ", stdout);
  185.                 atalk_print(p, length);
  186.                 return (1);
  187.  
  188.         case ETHERTYPE_AARP:
  189.                 aarp_print(p, length);
  190.                 return (1);
  191.  
  192.         case ETHERTYPE_LAT:
  193.         case ETHERTYPE_SCA:
  194.         case ETHERTYPE_MOPRC:
  195.         case ETHERTYPE_MOPDL:
  196.                 /* default_print for now */
  197.         default:
  198.                 return (0);
  199.         }
  200. }
  201.